# ----------------------------------------------------------------------
# DEFINE THE STRUCTURE FOR THE ECONOMY WITH PERFECT INFORMATION
# ----------------------------------------------------------------------
type CE_Economy_PInf
    #Parameters
    β::Float64     # Discount factor
    γ::Float64     # Risk aversion
    r::Float64     # Risk free rate
    θ::Float64     # Prob of reentering markets
    σ_d::Float64   # Small disturbance to default value
    nb1::Int64     # Points in b grid
    nb2::Int64     # Points in b grid
    nb::Int64      # Points in b grid
  	ny::Int64      # Points in y grid
  	Bval::Float64  # Value for B
    π_min::Float64 # Maximum misreport (lower bound)
    d0::Float64    # Default Cost
  	d1::Float64    # Default Cost
    ε::Float64     # Default Cost (dif)
  	η::Float64     # Output volatility
  	ρ::Float64     # Output persitence
    Πy::Matrix{Float64} # Output Markov matrix
    ΠT::Matrix{Float64}  #Markov matrix for types
    NQ::Float64    # Average number of quarters each type is in government
    zb::Float64    # Coupon payments
    mb::Float64    # 1/Maturity
    #Grids
    b_grid::Array{Float64,1}       #Grid for b
  	y_grid::Array{Float64,1}       #Grid for y
    ydef_grid_I::Array{Float64,1}  #Output if default
    ydef_grid_P::Array{Float64,1}  #Output if default
    Udef::Array{Float64,2}         #Utility if in default (exogenous)
    #Matrices to store results
    Wf::Array{Float64,3}    #Value function (if not in default)
    Wd::Array{Float64,2}    #Value function (if default today)
    Wr::Array{Float64,3}    #Value function (before repay)
    #Debt policies & prices
    q_mat::Array{Float64,3}  # Debt Prices - Baseline Model
    bp::Array{Float64, 3}    # Optimal debt policy
    #Default Decision
    default::Array{Float64,3}
    #Algorithm Options
    damp::Float64         # Dampening
    maxiter::Int64        # Max number of iterations
    save_final::Int64     # Set=1 to save final results
end



#-------------------------------------------------------------------------------
# Give initial values to the economy type
#-------------------------------------------------------------------------------

function ce_economy_pinf(;r    = 0.01,
		                β          = 0.9505,
                    γ          = 2.0,        
                    θ          = 0.0385,  
                    σ_d        = 0.0015,  
                    nb1        = 15,
                    nb2        = 33,
        	          ny         = 15,
                    zb         = 0.03,   
                    mb         = 0.05,
                    Bval       = 0.02,       
                    π_min      = -0.04,     
        	          d0         = -0.242,
        	          d1         = 0.325,
                    ε          = -0.0055,
                    NQ         = 32,
        	          η   	     = 0.02,    
        	          ρ          = 0.93,
                    damp       = 0.98,
                    maxiter    = 1200,
                    save_final = 0)

# Markov matrix for types
pp = 1-1/(NQ)            # Transition probability
ΠT = [pp 1-pp; 1-pp pp]; # Markov Matrix fro Types

#Grids: b, y
  b_grid1      = collect(linspace(  0.0,                        0.40,             nb1));
  b_grid2      = collect(linspace( b_grid1[end]+b_grid1[2],     1.15,             nb2));
  b_grid       = [b_grid1; b_grid2]
  nb           = length(b_grid)

  lny_grid,Πy = tauchen_fun(ny, ρ, η);
  y_grid      = exp.(lny_grid);
  ydef_grid_I = y_grid-max.((d0+ε)*y_grid+d1*y_grid.^2, 1e-14);
  ydef_grid_P = y_grid-max.((d0-ε)*y_grid+d1*y_grid.^2, 1e-14);

#Output & Utility if in default (exogenous)
  Udef = zeros(ny,2);
  u_fun_def(c,γ) = (c.^(1.0-γ))/(1.0-γ);
  for (i_y, y_v) in enumerate(y_grid)
  ydf_I = y_v-max((d0+ε)*y_v+d1*y_v.^2, 1e-14);
  ydf_P = y_v-max((d0-ε)*y_v+d1*y_v.^2, 1e-14);
  Udef[i_y,1] = u_fun_def(ydf_P,γ);
  Udef[i_y,2] = u_fun_def(ydf_I,γ);
  end

#Matrices to store results: Prices, Policies, & Conjectures
  q_mat    = ones(nb, ny, 2) / (1.0+r);
  bp 	     = zeros(nb, ny, 2);
  default  = zeros(nb, ny, 2);

#Matrices to store results: Value Functions
  Wf = -10*ones(nb, ny, 2);
  Wr = -10*ones(nb, ny, 2);
  Wd = -10*ones(ny, 2);


return CE_Economy_PInf( β, γ, r, θ, σ_d,
                     nb1, nb2, nb, ny, Bval, π_min, d0, d1, ε, η, ρ, Πy, ΠT, NQ,
                     zb, mb, b_grid, y_grid, ydef_grid_I, ydef_grid_P, Udef,
                     Wf, Wd, Wr, q_mat, bp, default, damp, maxiter, save_final )

end
